<!DOCTYPE html>
<html lang="en-US">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>面试-简述基础中剩下的部分BIO，NIO，粘包/拆包，多路复用等 | 惊蛰的博客</title>
    <meta name="generator" content="VuePress 1.8.2">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.11.2/css/all.css">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.11.2/css/v4-shims.css">
    <script src="https://use.fontawesome.com/releases/v5.11.2/js/all.js"></script>
    <script src="https://use.fontawesome.com/releases/v5.11.2/js/v4-shims.js"></script>
    <!--    #代码高亮引入必要库-->
    <link href="https://cdn.bootcss.com/highlight.js/8.0/styles/monokai_sublime.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/highlight.js/8.0/highlight.min.js"></script>
    <!--    动画库-->
    <link rel="stylesheet" href="https://www.kettle.net.cn/animate/animate.min.css">
    <!--    评论-->
    <script src="//unpkg.com/valine/dist/Valine.min.js"></script>
    <!--    aplayer-->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer@1.10.0/dist/APlayer.min.css">
    <script src="https://cdn.jsdelivr.net/npm/aplayer@1.10.0/dist/APlayer.min.js"></script>
    <!-- require MetingJS -->
    <script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>
    <!--    jq-->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <!--    backstretch 轮播图-->
    <script type="text/javascript" src="//cdn.bootcss.com/jquery-backstretch/2.0.4/jquery.backstretch.min.js"></script>
    <!-- 引用 bbtalk -->
    <script src="https://cdn.jsdelivr.net/npm/bbtalk@0.1.5/dist/bbtalk.min.js"></script>
    
    <meta name="description" content="惊蛰的博客">
    
    <link rel="preload" href="/assets/css/0.styles.c076dd71.css" as="style"><link rel="preload" href="/assets/js/app.8e64649f.js" as="script"><link rel="preload" href="/assets/js/17.9b1a1e45.js" as="script"><link rel="preload" href="/assets/js/4.84c4889c.js" as="script"><link rel="preload" href="/assets/js/37.a4ec9e64.js" as="script"><link rel="prefetch" href="/assets/js/1.19f63e1b.js"><link rel="prefetch" href="/assets/js/10.76457569.js"><link rel="prefetch" href="/assets/js/11.2fabe50b.js"><link rel="prefetch" href="/assets/js/12.29f3cbb3.js"><link rel="prefetch" href="/assets/js/13.5bbd6907.js"><link rel="prefetch" href="/assets/js/14.97c38b2b.js"><link rel="prefetch" href="/assets/js/15.a6ea704f.js"><link rel="prefetch" href="/assets/js/16.bf8c8fc8.js"><link rel="prefetch" href="/assets/js/18.bcc6785d.js"><link rel="prefetch" href="/assets/js/19.af8c6c71.js"><link rel="prefetch" href="/assets/js/2.63f6fb06.js"><link rel="prefetch" href="/assets/js/20.04b27695.js"><link rel="prefetch" href="/assets/js/21.0ecdd73f.js"><link rel="prefetch" href="/assets/js/22.5a2b263f.js"><link rel="prefetch" href="/assets/js/23.a9412068.js"><link rel="prefetch" href="/assets/js/24.aedb6bde.js"><link rel="prefetch" href="/assets/js/25.dfc2456b.js"><link rel="prefetch" href="/assets/js/26.e8e572f6.js"><link rel="prefetch" href="/assets/js/27.0fd0718f.js"><link rel="prefetch" href="/assets/js/28.60ae6b13.js"><link rel="prefetch" href="/assets/js/29.701ebcc0.js"><link rel="prefetch" href="/assets/js/3.315403c1.js"><link rel="prefetch" href="/assets/js/30.9b75bf1e.js"><link rel="prefetch" href="/assets/js/31.67f8b095.js"><link rel="prefetch" href="/assets/js/32.b87582bb.js"><link rel="prefetch" href="/assets/js/33.7c0ab263.js"><link rel="prefetch" href="/assets/js/34.d4c2e482.js"><link rel="prefetch" href="/assets/js/35.88a27070.js"><link rel="prefetch" href="/assets/js/36.ccd7bbb9.js"><link rel="prefetch" href="/assets/js/38.888b51fa.js"><link rel="prefetch" href="/assets/js/39.822d40c5.js"><link rel="prefetch" href="/assets/js/40.76c692f0.js"><link rel="prefetch" href="/assets/js/5.94499d86.js"><link rel="prefetch" href="/assets/js/6.5934ba2a.js"><link rel="prefetch" href="/assets/js/8.b3a395d6.js"><link rel="prefetch" href="/assets/js/9.81a3105a.js">
    <link rel="stylesheet" href="/assets/css/0.styles.c076dd71.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div><div data-v-43936cb4><div class="container" data-v-43936cb4 data-v-43936cb4><div class="ordinary" data-v-43936cb4><div data-v-43936cb4><a target="_self" href="/" class="title flat-box waves-effect waves-block author" data-v-43936cb4>
                        jingzhe
                    </a></div> <div class="menu navigation" data-v-43936cb4><ul class="nav-list-h m-pc" data-v-43936cb4><li data-v-43936cb4><a href="/" id="home" class="menuitem flat-box faa-parent animated-hover waves-effect waves-block" data-v-43936cb4><i class="fa fa-home fa-fw" data-v-43936cb4></i>博客
                            </a></li> <li data-v-43936cb4><a href="/archives/" id="archives" class="menuitem flat-box faa-parent animated-hover waves-effect waves-block" data-v-43936cb4><i class="fa fa-archive fa-fw" data-v-43936cb4></i>归档
                            </a></li> <li data-v-43936cb4><a href="/friends/" id="friends" class="menuitem flat-box faa-parent animated-hover waves-effect waves-block" data-v-43936cb4><i class="fa fa-link fa-fw" data-v-43936cb4></i>友链
                            </a></li> <li data-v-43936cb4><a href="/aboutPage/" id="about" class="menuitem flat-box faa-parent animated-hover waves-effect waves-block" data-v-43936cb4><i class="fa fa-info-circle fa-fw" data-v-43936cb4></i>关于
                            </a></li> <li data-v-43936cb4><a id="other" class="menuitem flat-box faa-parent animated-hover waves-effect waves-block" data-v-43936cb4><i class="fa fa-info-circle fa-fw" data-v-43936cb4></i>其他
                            </a> <ul class="list-v" data-v-43936cb4><li data-v-43936cb4><a class="menuitem flat-box header toggle-mode-btn cutover" data-v-43936cb4><i class="fas fa-moon fa-fw" data-v-43936cb4></i> 暗黑模式
                                    </a></li> <li data-v-43936cb4><hr data-v-43936cb4></li> <li data-v-43936cb4><a href="/bb/" class="menuitem flat-box faa-parent animated-hover" data-v-43936cb4>
                                        哔哔哔
                                    </a></li> <li data-v-43936cb4><a target="_blank" href="https://blog.jingzhe.xyz" class="menuitem flat-box faa-parent animated-hover" data-v-43936cb4>
                                        旧版博客
                                    </a></li> <hr data-v-43936cb4> <li data-v-43936cb4><a href="/categories/" class="menuitem flat-box faa-parent animated-hover" data-v-43936cb4><i class="fa fa-folder-open fa-fw" data-v-43936cb4></i>
                                        分类
                                    </a></li> <li data-v-43936cb4><a href="/tags/" id="v2getting-started" class="menuitem flat-box faa-parent animated-hover" data-v-43936cb4><i class="fa fa-tags fa-fw" data-v-43936cb4></i> 标签
                                    </a></li></ul></li></ul></div> <div class="m_search" data-v-43936cb4><form name="searchform" class="form u-search-form" data-v-43936cb4><i class="icon fa fa-search fa-fw" data-v-43936cb4></i> <input type="text" placeholder="Search..." class="input u-search-input" data-v-43936cb4></form></div></div> <div class="paper" data-v-43936cb4></div></div></div> <div id="archives-pjax" class="paper" data-v-bb8ac3a0><div class="homeCover" data-v-bb8ac3a0></div> <div class="row" data-v-bb8ac3a0><div class="col-span-24" data-v-bb8ac3a0><div id="anchorPoint" data-v-bb8ac3a0></div></div> <div id="main-body-pjax" class="main-body" data-v-bb8ac3a0><div class="paper-page" data-v-bb8ac3a0><div show="true" class="homepage" data-v-9fc62fe0 data-v-bb8ac3a0><div class="post-list" data-v-9fc62fe0 data-v-9fc62fe0><div class="post-wrapper" data-v-9fc62fe0><div class="headimg-div" data-v-9fc62fe0><!----></div> <div class="meta" data-v-9fc62fe0><h2 data-v-9fc62fe0>面试-简述基础中剩下的部分BIO，NIO，粘包/拆包，多路复用等</h2> <div data-v-9fc62fe0><div class="author" data-v-9fc62fe0><a href="https://blog.jingzhe.xyz" rel="nofollow" class="author-div" data-v-9fc62fe0><img src="https://blog.jingzhe.xyz/jingzhe/jpg/1593256062295.jpeg" data-v-9fc62fe0> <a data-v-9fc62fe0>Jingzhe</a></a></div> <div class="time" data-v-9fc62fe0><div data-v-9fc62fe0><i aria-hidden="true" class="fa fa-calendar-alt fa-fw" data-v-9fc62fe0></i> <span data-v-9fc62fe0>2020-11-30T15:55:35.000Z</span></div></div> <div class="guest" data-v-9fc62fe0><i class="fa fa-comment-dots fa-fw" data-v-9fc62fe0></i> <span data-v-9fc62fe0>9</span></div></div></div> <div class="article" data-v-9fc62fe0><div class="leancloud_visitors" data-v-9fc62fe0><div class="content__default" data-v-9fc62fe0><h5 id="简述基础中剩下的部分bio-nio-粘包-拆包-多路复用等"><a href="#简述基础中剩下的部分bio-nio-粘包-拆包-多路复用等" class="header-anchor">#</a> <strong>简述基础中剩下的部分BIO，NIO，粘包/拆包，多路复用等</strong></h5> <p><img src="https://i.loli.net/2020/12/02/1bCl5pJOPwQLKjY.png" alt=""></p> <h2 id="bio-nio和aio"><a href="#bio-nio和aio" class="header-anchor">#</a> <strong>BIO，NIO和AIO</strong></h2> <p><strong>简介：</strong></p> <blockquote><p>BIO：同步阻塞式IO，服务器实现模式为一个连接一个线程，即客户端有连接请求时服务器端就需要启动一个线程进行处理，如果这个连接不做任何事情会造成不必要的线程开销，当然可以通过线程池机制改善。</p></blockquote> <blockquote><p>NIO：同步非阻塞式IO，服务器实现模式为一个请求一个线程，即客户端发送的连接请求都会注册到多路复用器上，多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。</p></blockquote> <blockquote><p>AIO(NIO.2)：异步非阻塞式IO，服务器实现模式为一个有效请求一个线程，客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。</p></blockquote> <h3 id="bio"><a href="#bio" class="header-anchor">#</a> <strong>BIO</strong></h3> <blockquote><p><img src="https://i.loli.net/2020/12/02/ug8zDUsTCdBJMct.png" alt="">
阻塞IO，一个请求对应一个线程，线程是阻塞的，面向流的，只能单向读写</p></blockquote> <p>缺点：很显而易见，阻塞式IO、弹性伸缩能力强、多线程耗费资源</p> <p>场景：<strong>BIO方式适用于连接数目比较小且固定的场景，这种方式对服务器资源要求比较高</strong>，并发局限于应用中。</p> <h3 id="nio"><a href="#nio" class="header-anchor">#</a> <strong>NIO</strong></h3> <blockquote><p><img src="https://i.loli.net/2020/12/02/ZILvo8VTjXUSJlN.png" alt="">
同步非阻塞，服务器实现一个连接一个线程，即客户端发送的连接请求都会注册到多路复用器上，多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。NIO方式适用于连接数目多且连接比较短（轻操作）的架构，比如聊天服务器，并发局限于应用中，编程比较复杂，JDK1.4之后开始支持。每个客户端请求都会注册到Selector(多路复用器)，是面向缓冲的, 可以双向读写</p></blockquote> <p>相对于BIO来说优点就是非阻塞节约资源了</p> <p>缺点：NIO类库繁琐，复杂，可靠性不高，空轮询，会导致cpu100%</p> <p>场景：<strong>NIO适合处理连接数目特别多，但是连接比较短（轻操作）的场景</strong>，<strong>Jetty，Mina，ZooKeeper等都是基于java nio实现</strong>。</p> <p>NIO在JAVA中的代码（部分）</p> <div class="language- extra-class"><pre class="language-text"><code>import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

/**
 * 阻塞点this.selector.select();
 * 轮询器虽然是一个线程内部也是线程池
 */
public class NioSocket {
    private Selector selector;   //通道管理器(管理器)

    /**
     * 初始化Channel并绑定端口
     * @param port
     * @throws IOException
     */
    public void initServer(int port) throws IOException {
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(false);  //非阻塞
        serverChannel.socket().bind(new InetSocketAddress(port));

        this.selector = Selector.open();
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println(&quot;服务器已启动...&quot;);
    }

    /**
     * 监听轮询器
     * @throws IOException
     */
    public void listenSelector() throws IOException {
        //轮询监听selector
        while (true){
            //等待客户连接
            //select模型,多路复用
            //this.selector.select();   //在这里会阻塞,无论是连接还是客户端发送数据还是客户端关闭,这里都会触发
            this.selector.selectNow();   //这里不阻塞会立即执行
            Iterator&lt;SelectionKey&gt; iteKey = this.selector.selectedKeys().iterator();
            while (iteKey.hasNext()){
                SelectionKey key = iteKey.next();
                iteKey.remove();  //移除,防止重复处理
                //处理请求
                handler(key);
            }
        }
    }

    /**
     * 处理客户端请求
     * @param key
     */
    private void handler(SelectionKey key) throws IOException {
        if (key.isAcceptable()){  //处理连接请求
            //处理客户端连接请求事件
            ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
            SocketChannel socketChannel = serverChannel.accept();
            //接受客户端发送的信息时,需要给通道设置读权限
            socketChannel.configureBlocking(false);
            socketChannel.register(selector,SelectionKey.OP_READ);
        }else if(key.isReadable()){   //处理读请求
            //处理读事件
            SocketChannel socketChannel = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int readData = socketChannel.read(buffer);
            if (readData&gt;0){
                String info  = new String(buffer.array(),&quot;GBK&quot;).trim();
                System.out.println(&quot;服务端收到数据: &quot;+Thread.currentThread()+info);
            }else {
                System.out.println(&quot;客户端关闭了...&quot;);
                key.cancel();
            }
        }
    }

    public static void main(String[] args) throws IOException {
        NioSocket nio = new NioSocket();
        nio.initServer(8888);
        nio.listenSelector();
    }
}
</code></pre></div><h3 id="aio-nio-2"><a href="#aio-nio-2" class="header-anchor">#</a> <strong>AIO(NIO.2)</strong></h3> <blockquote><p>异步非阻塞IO，在此种模式下，用户进程只需要发起一个IO操作然后立即返回，等IO操作真正的完成以后，应用程序会得到IO操作完成的通知，此时用户进程只需要对数据进行处理就好了，不需要进行实际的IO读写操作，因为真正的IO读取或者写入操作已经由内核完成了。
<img src="https://i.loli.net/2020/12/02/dFDNOUpPs28ofw5.png" alt="https://blog.csdn.net/weixin_43122090/article/details/105462088"></p></blockquote> <h3 id="多路复用-channel"><a href="#多路复用-channel" class="header-anchor">#</a> <strong>多路复用（Channel）</strong></h3> <ul><li>Channel是一个对象，可以通过它读取和写入数据。通常我们都是将数据写入包含一个或者多个字节的缓冲区，然后再将缓存区的数据写入到通道中，将数据从通道读入缓冲区，再从缓冲区获取数据。</li> <li>Channel 类似于原I/O中的流（Stream），但有所区别：</li> <li>流是单向的，通道是双向的，可读可写。</li> <li>流读写是阻塞的，通道可以异步读写。</li></ul> <p>NIO是JDK1.4提供的操作，他的流还是流，没有改变，服务器实现的还是一个连接一个线程，当是：<code>客户端发送的连接请求都会注册到多路复用器上</code>，多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。NIO方式适用于连接数目多且连接比较短（轻操作）的架构，比如聊天服务器，并发局限于应用中，编程比较复杂，JDK1.4之后开始支持。</p> <p><img src="https://i.loli.net/2020/12/02/oCJDetfwlszS1bq.png" alt="">
上图清晰的描述了他们之间的关系</p> <h3 id="拆包-粘包"><a href="#拆包-粘包" class="header-anchor">#</a> <strong>拆包/粘包</strong></h3> <h4 id="为什么会出现粘包"><a href="#为什么会出现粘包" class="header-anchor">#</a> <strong>为什么会出现粘包</strong></h4> <p>分两个方面解释，一方面是发送方原因
我们都知道，TCP默认用的是Nagle算法，只做两件事：
1）只有上一分组得到确认，才会发送下一分组
2）收集多个小分组，在一个确认到来时一起发送
所以，正是这个算法造成了粘包现象</p> <p>另一方面就是接收方原因，
TCP接收到分组时，并不会立即发送至应用层进行处理，实际上，TCP会将分组放入缓存里，然后应用程序主动从缓存中读取，这样，如果TCP接受的速度远大于应用读取缓存的速度，多个包就会被存至缓存中，应用程序读的时候，就会读到好几个包首尾粘在一起</p> <h4 id="什么时候需要处理粘包现象"><a href="#什么时候需要处理粘包现象" class="header-anchor">#</a> <strong>什么时候需要处理粘包现象</strong></h4> <p>1）如果发送方发送的是同一数据的不同部分，比如一个比较大的文件分成多个碎片传递过来，这时候不需要处理粘包
2）但是如果多个分组并不相干，甚至是并列关系，我们就一定要处理粘包问题了，不然就会丢弃分组或者分组错误的情况出现了</p> <p><strong>如果处理粘包现象</strong>
1）发送方我们可以通过关闭Nagle算法来解决，使用TCP_NODELAY来关闭该算法
2）接收方的，接收方没办法处理粘包现象，我们只能通过应用层面来解决改问题
3）应用层面，可以在发送分组的时候，将数据的长度一并发送，或者通过规定固定符号起始固定符号结束（该方法简单好用）</p> <p>以上关于粘包内容摘抄整理自https://blog.csdn.net/prefect_boy/article/details/100035865</p> <hr> <p><strong>能力越强，责任越大。</strong></p> <p><strong>实事求是，严谨细致。</strong></p> <p><strong>（<a href="https://jingzhe.xyz/" target="_blank" rel="noopener noreferrer">惊蛰新博客<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>）</strong></p></div></div></div> <div data-v-9fc62fe0><div class="article_copyright" data-v-089751b8 data-v-9fc62fe0><div class="article_footer" data-v-089751b8><div class="content" data-v-089751b8><blockquote data-v-089751b8><p data-v-089751b8>博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议</p> <p data-v-089751b8>本文永久链接是：<a href="/2020/11/30/%E7%AE%80%E8%BF%B0%E5%9F%BA%E7%A1%80%E4%B8%AD%E5%89%A9%E4%B8%8B%E7%9A%84%E9%83%A8%E5%88%86bionio%E7%B2%98%E5%8C%85%E6%8B%86%E5%8C%85%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8%E7%AD%89/" style="display: block;" data-v-089751b8>/2020/11/30/%E7%AE%80%E8%BF%B0%E5%9F%BA%E7%A1%80%E4%B8%AD%E5%89%A9%E4%B8%8B%E7%9A%84%E9%83%A8%E5%88%86bionio%E7%B2%98%E5%8C%85%E6%8B%86%E5%8C%85%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8%E7%AD%89/</a></p></blockquote></div></div> <div class="new-meta-box" data-v-089751b8><div itemprop="dateUpdated" class="new-date" data-v-089751b8><a data-v-089751b8><i aria-hidden="true" class="fa fa-edit fa-fw" data-v-089751b8></i> <p data-v-089751b8>更新于：2020-11-30T15:55:35.000Z</p></a></div></div> <div class="prev-next" data-v-089751b8><a href="/2020/11/30/%E7%AE%80%E8%AE%BA%E5%BE%AE%E5%89%8D%E7%AB%AF%E7%9A%84%E6%84%8F%E4%B9%89%E4%B8%8E%E6%9C%AA%E6%9D%A5%E5%8F%91%E5%B1%95/" class="prev" data-v-089751b8><p class="title" data-v-089751b8><i aria-hidden="true" class="fa fa-chevron-left" data-v-089751b8></i>简论微前端的意义与发展</p></a> <a href="/2020/11/24/%E8%A7%A3%E5%86%B3-sub-filter-%E4%B8%8D%E8%83%BD%E6%9B%BF%E6%8D%A2-gzip-%E8%BF%87%E7%9A%84%E5%86%85%E5%AE%B9/" class="next" data-v-089751b8><p class="title" data-v-089751b8>解决 sub_filter 不能替换 Gzip 过的内容<i aria-hidden="true" class="fa fa-chevron-right" data-v-089751b8></i></p></a></div></div></div></div> <div class="article-comment" data-v-9fc62fe0><div class="comment" data-v-2ce08322 data-v-9fc62fe0><div class="post-list" data-v-2ce08322><div class="post-wrapper vcomment-div" data-v-2ce08322><em class="post-meta-item-text" data-v-2ce08322>阅读量 </em> <i class="leancloud-visitors-count" data-v-2ce08322>1000000</i> <div data-v-2ce08322></div></div></div></div></div></div></div></div> <div class="right-page" data-v-bb8ac3a0><div class="rightPage" data-v-1be37983 data-v-bb8ac3a0><div class="computer" data-v-1be37983 data-v-1be37983><div class="content paperMenu" style="transition:0s;" data-v-1be37983><div class="social-wrapper paper-navigation" data-v-1be37983><div data-v-1be37983><i class="fas fa-folder-open fa-fw" data-v-1be37983></i> <span data-v-1be37983>文章导航</span></div> <div class="navigationContent" data-v-1be37983><div data-v-1be37983><!----> <h2 class="paperlevel" data-v-1be37983><a id="bio-nio和aio" data-v-1be37983></a>BIO，NIO和AIO
                            </h2> <!----> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="bio" data-v-1be37983></a>BIO
                            </h3> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="nio" data-v-1be37983></a>NIO
                            </h3> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="aio-nio-2" data-v-1be37983></a>AIO(NIO.2)
                            </h3> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="多路复用-channel" data-v-1be37983></a>多路复用（Channel）
                            </h3> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="拆包-粘包" data-v-1be37983></a>拆包/粘包
                            </h3> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <!----> <h4 class="paperlevel" data-v-1be37983><a id="为什么会出现粘包" data-v-1be37983></a>为什么会出现粘包
                            </h4> <!----> <!----></div><div data-v-1be37983><!----> <!----> <!----> <h4 class="paperlevel" data-v-1be37983><a id="什么时候需要处理粘包现象" data-v-1be37983></a>什么时候需要处理粘包现象
                            </h4> <!----> <!----></div></div></div></div> <div class="content" data-v-1be37983><div class="head" data-v-1be37983><a href="/aboutPage/" class="avatar flat-box rectangle" data-v-1be37983><img src="https://blog.jingzhe.xyz/jingzhe/jpg/1593256062295.jpeg" data-v-1be37983></a> <p data-v-1be37983><span data-v-1be37983>微雨众卉新，一雷惊蛰始。</span></p></div> <div class="social-wrapper" data-v-1be37983><span data-v-1be37983><a href="" rel="external nofollow noopener noreferrer" target="_blank" class="social fab fa-github flat-btn" data-v-1be37983></a></span> <span data-v-1be37983><a href="mailto: 12363078673@qq.com" rel="external nofollow noopener noreferrer" target="_blank" class="social fas fa-envelope flat-btn" data-v-1be37983></a></span> <span data-v-1be37983><a href="https://blog.csdn.net/u013605060" rel="external nofollow noopener noreferrer" target="_blank" class="social fas fa-code flat-btn" data-v-1be37983></a></span> <span data-v-1be37983><a href="http://wpa.qq.com/msgrd?v=3&amp;uin=1263078673&amp;site=qq&amp;menu=yes" rel="external nofollow noopener noreferrer" target="_blank" class="social fa fa-qq flat-btn" data-v-1be37983></a></span></div></div> <div class="content" data-v-1be37983><div class="social-wrapper" data-v-1be37983><div data-v-1be37983><i class="fas fa-folder-open fa-fw" data-v-1be37983></i> <span data-v-1be37983>文章分类</span></div> <div data-v-1be37983><ul class="entry navigation" data-v-1be37983><li data-v-1be37983><a href="/categories/笔记/" id="blogcategoriesmac" class="flat-box" data-v-1be37983><div class="name" data-v-1be37983>笔记</div> <div class="badge" data-v-1be37983>(14)</div></a></li><li data-v-1be37983><a href="/categories/作品集/" id="blogcategoriesmac" class="flat-box" data-v-1be37983><div class="name" data-v-1be37983>作品集</div> <div class="badge" data-v-1be37983>(1)</div></a></li><li data-v-1be37983><a href="/categories/随笔/" id="blogcategoriesmac" class="flat-box" data-v-1be37983><div class="name" data-v-1be37983>随笔</div> <div class="badge" data-v-1be37983>(1)</div></a></li><li data-v-1be37983><a href="/categories/喵喵/" id="blogcategoriesmac" class="flat-box" data-v-1be37983><div class="name" data-v-1be37983>喵喵</div> <div class="badge" data-v-1be37983>(2)</div></a></li><li data-v-1be37983><a href="/categories/创作集/" id="blogcategoriesmac" class="flat-box" data-v-1be37983><div class="name" data-v-1be37983>创作集</div> <div class="badge" data-v-1be37983>(1)</div></a></li></ul></div></div></div> <div class="content" data-v-1be37983><div class="social-wrapper" data-v-1be37983><div data-v-1be37983><i class="fas fa-tags fa-fw" data-v-1be37983></i> <span data-v-1be37983>热门标签</span></div> <div class="word-cloud" data-v-1be37983><a href="/tags/jenkins/" style="font-size:15px;" data-v-1be37983>jenkins</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/vue/" style="font-size:18px;" data-v-1be37983>vue</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/JS/" style="font-size:24px;" data-v-1be37983>JS</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/JAVA/" style="font-size:15px;" data-v-1be37983>JAVA</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/Trilateration/" style="font-size:15px;" data-v-1be37983>Trilateration</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/Google/" style="font-size:15px;" data-v-1be37983>Google</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/pjax/" style="font-size:15px;" data-v-1be37983>pjax</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/%E7%94%B5%E5%BD%B1/" style="font-size:15px;" data-v-1be37983>电影</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/%E5%85%AB%E4%BD%B0/" style="font-size:15px;" data-v-1be37983>八佰</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/%E5%89%8D%E7%AB%AF/" style="font-size:18px;" data-v-1be37983>前端</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/css/" style="font-size:18px;" data-v-1be37983>css</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/docker/" style="font-size:15px;" data-v-1be37983>docker</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/nginx/" style="font-size:18px;" data-v-1be37983>nginx</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/rtmp/" style="font-size:15px;" data-v-1be37983>rtmp</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/ffmpeg/" style="font-size:18px;" data-v-1be37983>ffmpeg</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/element-ui/" style="font-size:15px;" data-v-1be37983>element-ui</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/nodejs/" style="font-size:15px;" data-v-1be37983>nodejs</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/shake/" style="font-size:15px;" data-v-1be37983>shake</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/DoraemonKit/" style="font-size:15px;" data-v-1be37983>DoraemonKit</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/%E6%BB%B4%E6%BB%B4/" style="font-size:15px;" data-v-1be37983>滴滴</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/BIO/NIO/AIO/" style="font-size:15px;" data-v-1be37983>BIO/NIO/AIO</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/%E6%8F%92%E4%BB%B6/" style="font-size:15px;" data-v-1be37983>插件</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/HTTP/HTTPS/" style="font-size:15px;" data-v-1be37983>HTTP/HTTPS</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/TCPIP/" style="font-size:15px;" data-v-1be37983>TCPIP</a></div></div></div> <div class="content" data-v-1be37983><div class="social-wrapper" data-v-1be37983><div data-v-1be37983><i class="fas fa-bullhorn fa-fw" data-v-1be37983></i> <span data-v-1be37983>公告</span></div> <div data-v-1be37983>
                        本站使用VuePress创建全站，还在不断完善中
                    </div></div></div> <div class="content" data-v-1be37983><div class="social-wrapper" data-v-1be37983><div data-v-1be37983><i class="fas fa-award fa-fw" data-v-1be37983></i> <span data-v-1be37983>站点信息</span></div> <div class="webinfo" data-v-1be37983><div class="webinfo-item" data-v-1be37983><div data-v-1be37983>文章数目：</div> <div data-v-1be37983>58 篇</div></div> <div class="webinfo-item" data-v-1be37983><div data-v-1be37983>已运行时间：</div> <div id="webinfo-runtime-count" data-v-1be37983>162 天</div></div> <div class="webinfo-item" data-v-1be37983><div data-v-1be37983>更新时间时间：</div> <div id="webinfo-runtime-count" data-v-1be37983>3 天前更新</div></div></div></div></div></div></div></div></div></div></div></div><div class="global-ui"></div></div>
<script src="/assets/js/app.8e64649f.js" defer></script><script src="/assets/js/17.9b1a1e45.js" defer></script><script src="/assets/js/4.84c4889c.js" defer></script><script src="/assets/js/37.a4ec9e64.js" defer></script>
<!-- 加入音乐-->
<div style="max-width: 750px;margin: 0 auto;padding: 40px;display: none;" id="meetingJs">
    <meting-js server="netease" type="playlist" id="567087780" list-max-height=150px></meting-js>
</div>
<!--全屏遮挡-->
<div class="fullScreen" style=""></div>

<canvas width="1413" height="968"
        style="position: fixed; left: 0px; top: 0px; z-index: 2147483647; pointer-events: none;"></canvas>
<!--鼠标特效-->
<script src="https://cdn.jsdelivr.net/gh/zyoushuo/Blog/hexo/js/mouse_click.js"></script>
<script>
    // 写一个简单的pjax，适配于vuepress
    $(function () {
        function pjax(href, type) {
            //为了seo的优化，不支持方法直接跳转
            if (!history.pushState) {
                window.location.href = href;
            }
            let newHref = href;
            $.ajax({
                url: newHref, success: function (result) {
                    let resultObj = $(result);
                    //获取标题
                    let newTitle = resultObj.filter("title").text();
                    //循环Script标签，重新加载拥有defer的
                    $("script[defer]").remove();
                    $(result).filter('script[defer]').each(function () {
                        $("body").append(this.outerHTML);
                    })
                    $("#main-body-pjax").after("<div style='display: none;' id='main-body-pjax-other' class='"+$("#main-body-pjax").attr('class')+"'></div>");
                    $("#main-body-pjax-other")[0].innerHTML = resultObj.find("div[id=main-body-pjax]").innerHTML;
                    let state = ({
                        url: newHref, title: newTitle
                    });
                    if (type === 1) {
                        window.history.pushState(state, newTitle, newHref);
                    }
                    document.title = newTitle
                    //滚回顶部
                    // $('html, body').animate({scrollTop: 0}, 'slow');
                    //背景再次被重置
                    if (window.localStorage.getItem('cutoverColor') === "false") {
                        $(".fullScreen").css("background","#000")
                    }
                }
            });
        }

        // 手写一个简易版本的pjax，适用于vuepress
        $('body').on('click', 'a', function (e) {
            e.preventDefault();
            if (typeof $(this).attr("href") != "undefined") {
                pjax($(this).attr("href"), 1);
            }
        })
        window.addEventListener('popstate', function (evt) {
            let oldHref = evt.state.url;
            pjax(oldHref, 0);
        }, false);
    })


    window.onload = function () {
        //防止哔哔哔模块不显示
        bbtalk.init({
            appId: "gbNUwY2ePs3khwpWCJvSNMC5-MdYXbMMI",
            appKey: "ObQ0ANDmaRwvTREmMpzN4WNv",
            serverURLs: 'https://gbnuwy2e.api.lncldglobal.com'
        })
        //音乐模块显示
        $("#meetingJs").show();
        //背景切换图
        $.backstretch(
            ["https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/006.jpg",
                "https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/051.jpg",
                "https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/034.jpg",
                "https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg",
                "https://api.mtyqx.cn/api/random.php",
            ], {
                fade: 750, duration: 4000, speed: 500
            }
        );
        //头部，返回到顶部展示，右侧菜单的展示规则
        let t = document.documentElement.scrollTop || document.body.scrollTop;
        headShow(t);
        backTopShow(t);
        rightPageMenuShow(t);
        //事件委托 (触发跳转)文章导航
        try {
            $("body").on('click', '.navigationContent', function (event) {
                let id = event.target.getElementsByTagName('a')[0].id;
                scroll(0, document.getElementById(id).offsetTop - 85);
            })
        } catch (e) {
        }
    }

    //移动滚动条
    function scroll(currentY, targetY) {
        // 计算需要移动的距离
        let needScrollTop = targetY - currentY
        let _currentY = currentY
        setTimeout(() => {
            // 一次调用滑动帧数，每次调用会不一样
            const dist = Math.ceil(needScrollTop / 10)
            _currentY += dist
            window.scrollTo(_currentY, currentY)
            // 如果移动幅度小于十个像素，直接移动，否则递归调用，实现动画效果
            if (needScrollTop > 10 || needScrollTop < -10) {
                scroll(_currentY, targetY)
            } else {
                window.scrollTo(_currentY, targetY)
            }
        }, 1)
    }

    /*监听滚动条，显示或者隐藏某些元素（右侧文章锚点和头部）*/
    window.onscroll = function () {
        let t = document.documentElement.scrollTop || document.body.scrollTop;
        headShow(t);
        backTopShow(t);
        rightPageMenuShow(t);
    }

    function headShow(t) {
        let container = document.querySelector('.container');//container 显示
        let height = (document.querySelector('.homeCover').offsetHeight) -
            (document.querySelector('.container').style.height);
        container.style.display = (t >= (height - 50)) ? "block" : "none";
    }

    function backTopShow(t) {
        try {
            let backTop = document.querySelector('.footer-up');//footer-up 显示
            backTop.style.display = (t >= 30) ? "block" : "none";
        } catch (e) {
        }
    }

    function rightPageMenuShow(t) {
        try {
            let rightPageMenu = document.querySelector('.paperMenu');//footer-up 显示
            rightPageMenu.className = (t >= 10) ? "content paperMenu suspension" : "content paperMenu";
        } catch (e) {
        }
    }


</script>


<script>
    //暗黑模式
    let cutoverColor = false;
    $(function () {
        if (window.localStorage.getItem('cutoverColor') === "false") {
            //线程独占
            setTimeout(function () {
                darkMode();
            }, 0);
        }
        $("body").on('click', '.cutover', function () {
            darkMode();
        })
    })

    function darkMode() {
        cutoverColor = !cutoverColor;
        window.localStorage.setItem('cutoverColor', !cutoverColor);
        if (cutoverColor) {
            document.documentElement.style.setProperty('--main', '#515a6e');
            document.documentElement.style.setProperty('--mainfont', '#fff');
            document.documentElement.style.setProperty('--headfont', '#fff');
            document.documentElement.style.setProperty('--color-list', '#fff');
            document.documentElement.style.setProperty('--color-tag', '#fff');
            $(".fullScreen").css("background","#000");
        } else {
            document.documentElement.style.setProperty('--main', '#ffff');
            document.documentElement.style.setProperty('--mainfont', '#515a6e');
            document.documentElement.style.setProperty('--headfont', '#2c3e50');
            document.documentElement.style.setProperty('--color-list', '#666');
            document.documentElement.style.setProperty('--color-tag', '#999');
            $(".fullScreen").css("background","");
        }
    }
</script>

<style>
    a {
        text-decoration: none
    }

    body {
        margin: 0 auto;
    }backstretch-item

    .fullScreen {
        left: 0px;
        top: 0px;
        overflow: hidden;
        margin: 0px;
        padding: 0px;
        height: 100%;
        width: 100vw;
        z-index: -999998;
        position: fixed;
    }
</style>
</body>
</html>
